﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Rekenmachine
{
    delegate Breuk DelegateBreukenBewerking(Breuk b1, Breuk b2);
    class ProgrammeerbareBreukContainer : BreukContainer
    {
        /// <summary>
        /// Doet de bewerking, aangeduid door delegateBreukenBewerking op de hele breukenlijst.
        /// </summary>
        /// <param name="delegateBreukenBewerking">De bewerking</param>
        /// <returns>Het resultaat</returns>
        public Breuk doeBewerking(DelegateBreukenBewerking delegateBreukenBewerking)
        {
            Breuk temp = null;
            if (breuken.Count > 0)
            {
                temp = new Breuk(breuken[0].Teller, breuken[0].Noemer);
                for (int i = 1; i < breuken.Count; i++)
                {
                    temp = delegateBreukenBewerking(temp, Breuken[i]);
                }
            }
            return temp;

        }
        /// <summary>
        /// Doet de bewerking, aangeduid door delegateBreukenBewerking op de hele breukenlijst.
        /// Indien de lijst te klein is, beginnen we van voren af aan.
        /// </summary>
        /// <param name="delegateBreukenBewerking">De bewerking</param>
        /// <param name="aantal">Hoeveel bewerkingen</param>
        /// <returns></returns>
        public Breuk doeBewerking(DelegateBreukenBewerking delegateBreukenBewerking, int aantal)
        {
            while (aantal > breuken.Count)
            { 
                breuken.AddRange(breuken.GetRange(0,breuken.Count));     
            }
            breuken.RemoveRange(aantal, breuken.Count - aantal);
            Breuk temp = null;
            if (breuken.Count > 0)
            {
                temp = new Breuk(breuken[0].Teller, breuken[0].Noemer);
                for (int i = 1; i < breuken.Count; i++)
                {
                    temp = delegateBreukenBewerking(temp, Breuken[i]);
                }
            }
            return temp;

        }
        public String doeBewerking(DelegateBreukenBewerking[] delegateBreukenBewerkingen, String[] operanden)
        {
            String output="";
            int i=0;
            Breuk temp = new Breuk(breuken[0].Teller, breuken[0].Noemer);
            output = output+temp.ToString()+" "+operanden[0]+ " ";
            foreach(DelegateBreukenBewerking d in delegateBreukenBewerkingen)
            {
                i++;
                output = output + Breuken[i].ToString();

                if (!(i >= operanden.Length))
                {
                    output = output +" "+operanden[i]+" ";
                }
                temp = d(temp, Breuken[i]);
            }
            temp.Vereenvoudig();
            output = output + "= " + temp.ToString();



            return output;
        }

        public override String ToString()
        {
            StringBuilder uitvoer = new StringBuilder("\nLijst van de huidige breuken:\n");
            uitvoer.Append("\n\nVan klein naar groot: ");
            breuken.Sort(delegate(Breuk b1, Breuk b2) { return b1.CompareTo(b2); });
            breuken.ForEach(delegate(Breuk b) { uitvoer.Append(String.Format("{0}/{1} ", b.Teller, b.Noemer)); });

            uitvoer.Append("\nVan groot naar klein: ");
            breuken.Sort(delegate(Breuk b1, Breuk b2) { return b2.CompareTo(b1); });
            breuken.ForEach(delegate(Breuk b) { uitvoer.Append(String.Format("{0}/{1} ", b.Teller, b.Noemer)); });
            return uitvoer.ToString();
        }
    }
}
